﻿function ECommerceProductViewModel(context) {

    var self = this;

    var spinner = new SpinnerModel();

    var productsByTag = context.spaRuntime.findRouteByName('productsByTag');

    var product = ko.observable(null);
    var recommendedProducts = new ECommerceRecommendationsViewModel(context);

    var productReviews = (function () {
        var reviews = ko.observableArray([]);
        var pager = new PagerCountModel(function (page) {
            return getPageUrl(page, pageSize());
        });
        
        var pageNumber = pager.pageNumber;
        var pageSize = pager.pageSize;
        var totalCount = pager.itemsCount;

        var addReviewUrl = ko.computed(function() {
            var prod = product();
            if (!prod) return null;
            return context.spaRuntime.findRouteByName('productReviewNew').formatHash({
                id: prod.id()
            });
        });
        
        function getEditReviewUrl(review) {
            var prodId = product().id();
            var rid = review.id();
            return context.spaRuntime.findRouteByName('productReviewEdit').formatHash({
                id: prodId,
                reviewId: rid
            });
        }

        function getPageUrl(pn, ps) {
            var spaRuntime = context.spaRuntime;
            var route = spaRuntime.getCurrentRoute();
            var arg = spaRuntime.getCurrentArgs();
            arg = $.extend({}, arg, {
                pageNumber: pn,
                pageSize: ps
            });
            return route.formatHash(arg);
        }

        function reload(prodId, pn, ps) {
            pageNumber(pn);
            pageSize(ps);
            
            var api = context.api();

            spinner.enter();
            api.reviews.listForProduct(prodId, pn, ps, function (raw) {
                spinner.leave();
                var items = raw.reviews;
                totalCount(raw.count);
                
                var res = [];
                for (var i = 0; i < items.length; i++) {
                    res.push(new ProductReviewModel(items[i]));
                }
                reviews(res);
            }, function () {
                spinner.leave();
            });
        }

        return {
            pager: pager,
            pageNumber: pageNumber,
            pageSize : pageSize,
            reload: reload,
            reviews: reviews,
            getEditReviewUrl: getEditReviewUrl,
            addReviewUrl: addReviewUrl
        };
    })();

    var editUrl = ko.computed(function () {
        var pr = product();
        if (!pr) return null;
        return context.spaRuntime.findRouteByName('productEdit').formatHash({
            id: pr.id()
        });
    });

    function addToCart() {
        var pr = product();
        context.addToCart(pr);
    }

    function reloadRecommendations(prodId) {
        recommendedProducts.reload([prodId]);
    }

    function reloadProduct(prodId) {
        var api = context.api();
        spinner.enter();
        api.products.getDetailsById(prodId, function (response) {
            spinner.leave();

            var pr = new FullProductModel(response);
            product(pr);

            var sessionTrackItem = {
                userId: context.userEmail(),
                prodId: pr.id()
            };
            api.session.postItem(sessionTrackItem);
            
            var prevProduct = context.getLastVisitedProduct();
            
            if (prevProduct !== null)
                api.recommendations.addTraversal(prevProduct, pr.id());
            
            context.addVisitedProduct(pr);

        }, function () {
            spinner.leave();
        });
        reloadRecommendations(prodId);
    }
    
    function showFor(args) {
        var prodId = args.id;

        var pn = 1;
        var ps = 10;
        
        if (args) {
            if (args.pageNumber) pn = parseInt(args.pageNumber);
            else pn = 1;
            if (args.pageSize) ps = parseInt(args.pageSize);
            else ps = 10;
        }

        reloadProduct(prodId);

        productReviews.reload(prodId, pn, ps);
    }

    function getByTagUrl(tag) {
        return productsByTag.formatHash({
            tag: tag
        });
    }

    function getProductUrl(pr) {
        var productInfoRoute = context.spaRuntime.findRouteByName('product');
        return productInfoRoute.formatHash({
            id: pr.id()
        });
    }

    self.product = product;
    self.addToCart = addToCart;
    self.productReviews = productReviews;
    self.showFor = showFor;
    self.editUrl = editUrl;
    self.getByTagUrl = getByTagUrl;
    self.getProductUrl = getProductUrl;
    self.recommendedProducts = recommendedProducts;
}

